package com.jumi.microservice.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jumi.microservice.constant.ExceptionEnum;
import com.jumi.microservice.constant.NumberConstant;
import com.jumi.microservice.constant.StatusEnum;
import com.jumi.microservice.domain.Department;
import com.jumi.microservice.domain.dto.DepartmentDTO;
import com.jumi.microservice.domain.vo.DepartmentVO;
import com.jumi.microservice.mapper.DepartmentMapper;
import com.jumi.microservice.service.DepartmentService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 部门表 服务实现类
 * </p>
 *
 * @author liuz
 * @since 2020-07-18
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class DepartmentServiceImpl extends ServiceImpl<DepartmentMapper, Department> implements DepartmentService {

    @Override
    public void insert(DepartmentDTO department){
        ExceptionEnum.FAIL_NULL.doThrowIf(department==null);
        Department r = dto2Po(department);

        r.setCreateTime(LocalDateTime.now());
        r.setUpdateTime(LocalDateTime.now());
        //暂时写死的两个值
        r.setCreater("admin");
        r.setModifier("admin");
        //保存部门信息
        baseMapper.insert(r);
    }

    @Override
    public void delete(Long id){
        Department dep = baseMapper.selectById(id);
        //根目录不能删除
        ExceptionEnum.FAIL_DEPARTMENT_DEL1.doThrowIf(dep.getParentId()==0);
        //启用状态下的部门，不能删除
        ExceptionEnum.FAIL_DEPARTMENT_DEL2.doThrowIf(dep.getStatus()== StatusEnum.STATUS_YES.getCode());
        //该部门下有下级部门，不能删除
        int count  = baseMapper.selectCount(
            Wrappers.<Department>lambdaQuery()
                .eq(Department::getIsDel,StatusEnum.STATUS_NO.getCode())
                .eq(Department::getParentId,dep.getId())
        );
        ExceptionEnum.FAIL_DEPARTMENT_DEL3.doThrowIf(count > 0);
        //该部门下有账号关联不能删除
        //.......

        dep.setIsDel(StatusEnum.STATUS_YES.getCode());
        dep.setUpdateTime(LocalDateTime.now());
        dep.setModifier("admin");
        baseMapper.updateById(dep);
    }

    @Override
    public void updateDepartment(DepartmentDTO vo){
        Department r = dto2Po(vo);
        r.setUpdateTime(LocalDateTime.now());
        r.setModifier("admin");
        baseMapper.updateById(r);
    }

    @Override
    public DepartmentDTO selectById(Long id){
        ExceptionEnum.FAIL_ID_NULL.doThrowIf(id==null);
        Department dep = baseMapper.selectById(id);
        ExceptionEnum.FAIL_NULL.doThrowIf(dep==null);
        DepartmentDTO departmentDTO = po2Dto(dep);
        return departmentDTO;
    }

    @Override
    public void enableStatus(Long id, Integer status){
        Department dep = baseMapper.selectById(id);
        dep.setStatus(status);
        dep.setUpdateTime(LocalDateTime.now());
        dep.setModifier("admin");
        baseMapper.updateById(dep);
    }

    /**
     * 根据角色id获取权限
     * @param id 角色id
     * @return
     */
    @Override
    public List<DepartmentVO> selectSonDepartmentId(Long id) {
        //先获取根目录
        List<Department> list = baseMapper.selectList(
                Wrappers.<Department>lambdaQuery()
                        .eq(Department::getIsDel,StatusEnum.STATUS_NO.getCode())
                        .eq(Department::getParentId, id));
        //获取子菜单
        List<DepartmentVO> vos = list.stream().map(po -> {
            DepartmentVO vo = po2Vo(po);
            getChildren(vo);
            return vo;
        }).collect(Collectors.toList());
        return vos;
    }

    /**
     * 根据父菜单获取子菜单
     * @param vo
     */
    private void getChildren(DepartmentVO vo){
        //获取当前的子菜单
        List<Department> list = baseMapper.selectList(
                Wrappers.<Department>lambdaQuery()
                        .eq(Department::getParentId,vo.getId())
                        .eq(Department::getIsDel,StatusEnum.STATUS_NO.getCode()));
        List<DepartmentVO> vos = list.stream().map(p->{
            DepartmentVO vop = po2Vo(p);
            getChildren(vop);
            return vop;
        }).collect(Collectors.toList());
        vo.setChildren(vos);
    }

    /**
     * po->vo
     * @param p
     * @return
     */
    private DepartmentVO po2Vo(Department p){
        DepartmentVO vo = null;{
            try {
                vo = p.clone(DepartmentVO.class);
            }catch (Exception e){
                ExceptionEnum.FAIL_CHANGE.newException();
            }
        }
        return vo;
    }

    /**
     * 对象转换 po->dto
     * @param po
     * @return
     */
    private DepartmentDTO po2Dto(Department po){
        DepartmentDTO r = null;
        try {
            r = po.clone(DepartmentDTO.class);
        }catch (Exception e){
            ExceptionEnum.FAIL_CHANGE.newException();
        }
        return r;
    }


    /**
     * 对象转换 dto->do
     * @param vo
     * @return
     */
    private Department dto2Po(DepartmentDTO vo){
        Department r = null;
        try {
            r = vo.clone(Department.class);
        }catch (Exception e){
            ExceptionEnum.FAIL_CHANGE.newException();
        }
        return r;
    }
}
